package com.brave.user.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.brave.base.*;
import com.brave.file.service.FileService;
import com.brave.user.dto.*;
import com.brave.user.entity.MCUserBaseInfo;
import com.brave.user.entity.MCUserInviteMappingEntity;
import com.brave.user.entity.MCUserSignDetailEntity;
import com.brave.user.entity.MCUserSignInfoEntity;
import com.brave.user.repository.MCUserBaseInfoRepository;
import com.brave.user.repository.MCUserInviteMappingRepository;
import com.brave.user.repository.MCUserSignDetailRepository;
import com.brave.user.repository.MCUserSignInfoRepository;
import com.brave.utils.AliOSSConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserUpdateService extends BaseService
{
    @Autowired
    RedisKit redisKit;
    @Autowired
    private MCUserBaseInfoRepository userBaseInfoRepository;
    @Autowired
    private MCUserInviteMappingRepository userInviteMappingRepository;
    @Autowired    //文件上传
    private FileService fileService;
    @Autowired
    private OSS ossClientBuilder;
    @Value("${invite.user.url.prefix}")
    private String qrCodeContent;
    @Value("${upload.file.root.path}")
    private String rootPath;
    @Autowired
    private MCUserSignDetailRepository userSignDetailRepository;
    @Autowired
    private MCUserSignInfoRepository userSignInfoRepository;
    
    
    
    /**
     * 2019年8月23日 15:08:26
     * 用户注册
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String register(RegisterDTO dto)
    {
        //查询手机号是否被占用
        MCUserBaseInfo userInfo =userBaseInfoRepository.findFirstByPhone(dto.getPhone());
        if(null != userInfo && 0 < userInfo.getId())
        {
            return paramException("手机号被占用.");
        }
        String verifyCode = redisKit.getValue(dto.getPhone());
        if("".equals(verifyCode))
        {
            return paramException("验证码已过期.");
        }
        //参数错误
        if(!verifyCode.equals(dto.getVerifyCode()))
        {
            return paramException("验证码错误.");
        }
        //开始注册流程
        Date now = new Date();
        String nickName = dto.getPhone().substring(0, 3);
        MCUserBaseInfo user = new MCUserBaseInfo();
        user.setUserName(String.format("%s%s%s", "用户", nickName, "****"));
        user.setLoginName(dto.getPhone());
        user.setNickName(String.format("%s%s%s", "用户", nickName, "****"));
        user.setPassword(MD5Kit.MD5Encode(dto.getPassword()));
        user.setPhone(dto.getPhone());
        user.setToken("");
        user.setAge(0);
        user.setIdCard("");
        user.setHeadUrl("");
        user.setIdCardFront("");
        user.setHandIdCard("");
        user.setIdCardBack("");
        user.setSex("M");
        user.setDeviceType("AD");
        user.setDeviceId(dto.getDeviceId() == null ? "" : dto.getDeviceId());
        user.setCreditScore(BigDecimal.ZERO);
        user.setIsVip(0);
        user.setVipLevel(0);
        user.setLatitude(dto.getLatitude());
        user.setLongitude(dto.getLongitude());
        user.setBalance(BigDecimal.ZERO);
        user.setBeanBalance(BigDecimal.ZERO);
        user.setRedDiamond(0);
        user.setGreenDiamond(0);
        user.setBlueDiamond(0);
        user.setCreateDate(now);
        user.setLastLoginDate(now);
        user.setAlipay("");
        user.setWechat("");
        user.setWeibo("");
        user.setQrcodeUrl("");
        user.setRegionCode("");
        user.setDomainCode("");
        user.setComment("");
        long userId = userBaseInfoRepository.save(user).getId();
        //查询推荐人的手机号是否存在
        MCUserBaseInfo inviteUserInfo = userBaseInfoRepository.findFirstByPhone(dto.getInviteUserPhone());
        if(null != inviteUserInfo && 0 < inviteUserInfo.getId())
        {
            MCUserInviteMappingEntity mapping = new MCUserInviteMappingEntity();
            mapping.setInviteUserId(inviteUserInfo.getId());
            mapping.setUserId(userId);
            mapping.setCreateDate(now);
            userInviteMappingRepository.save(mapping);
            //邀请了一个人以后的活动措施
            //TODO
        }
        //上传二维码图片
        try
        {
            String qrCode = String.format("%s%d", qrCodeContent, userId);
            //放置二维码图片位置
            
            File file = new File(rootPath + File.separator + "QRCode" + File.separator + userId + ".png");
            InputStream is = new FileInputStream(file);
            ossClientBuilder.putObject(AliOSSConfig.ALI_OSS_BUCKET_NAME, file.getName(), is);
            user.setQrcodeUrl(String.format("%s%s", "https://has-free-bucket.oss-cn-shenzhen.aliyuncs.com/", file.getName()));
            userBaseInfoRepository.save(user);
            is.close();
            ossClientBuilder.shutdown();
        }catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
        return success();
    }
    
    /**
     * 2019年8月23日 14:44:34
     * 找回密码
     * @param dto
     * @return
     */
    public String findOutPassword(FindOutPasswordDTO dto)
    {
        //查询出对应的用户数据
        String verifyCode = redisKit.getValue(dto.getPhone());
        if("".equals(verifyCode))
        {
            return paramException("验证码已过期.");
        }
        //参数错误
        if(!verifyCode.equals(dto.getVerifyCode()))
        {
            return paramException("验证码错误.");
        }
        //可以修改密码
        MCUserBaseInfo userInfo = userBaseInfoRepository.findFirstByPhone(dto.getPhone());
        userInfo.setPassword(MD5Kit.MD5Encode(dto.getNewPassword()));
        userBaseInfoRepository.save(userInfo);          //更新用户密码
        return success("操作成功");
    }


    /**
     * 2019年8月23日 15:33:24
     * 用户登录
     * @param dto
     * @return
     */
    public String doLogin(DoLoginDTO dto)
    {
        MCUserBaseInfo userInfo = userBaseInfoRepository.findFirstByPhoneAndPassword(dto.getAccount(), MD5Kit.MD5Encode(dto.getPassword()));
        if(null != userInfo && 0 < userInfo.getId())
        {
            String token = TokenGenerator.generate(userInfo.getPassword(), userInfo.getUserName());
            
            //更新Redis中的token数据
            RedisUserInfo redisUserInfo = new RedisUserInfo();
            //更新Redis
            redisKit.delValue(userInfo.getToken());
            //更新用户信息
            BeanUtils.copyProperties(userInfo, redisUserInfo);
            redisUserInfo.setToken(token);
            redisKit.saveTempValue(token, redisUserInfo, TimeUnit.DAYS, 30);
            //更新用户的Token令牌信息
            userInfo.setToken(token);
            userBaseInfoRepository.save(userInfo);
            //存放用户信息
            Map<String, Object> resultMap = new HashMap<>(3);
            resultMap.put("token", token);
            return success(resultMap);
        }else
        {
            return paramException("登录用户名或密码错误.");
        }
    }
    
    
    

    /**
     * 2019年8月23日 20:17:19
     * 更新用户头像
     * @param redisUserInfo
     * @param headImage
     * @return
     */
    public String updateHeadImage(RedisUserInfo redisUserInfo, MultipartFile headImage)
    {
        //公用文件上传
        String resultStr = fileService.uploadFile(headImage, redisUserInfo);
        JSONObject uploadResult = JSONObject.parseObject(resultStr);
        
        //更新头像信息
        Optional<MCUserBaseInfo> userOptional = userBaseInfoRepository.findById(redisUserInfo.getId());
        if(userOptional.isPresent())
        {
            MCUserBaseInfo userInfo = userOptional.get();
            userInfo.setHeadUrl(uploadResult.getString("fileUrl"));
            redisUserInfo.setHeadUrl(uploadResult.getString("fileUrl"));
            //先删除redis中的数据
            redisKit.delValue(redisUserInfo.getToken());
            //再次存入数据
            redisKit.saveTempValue(redisUserInfo.getToken(), redisUserInfo, TimeUnit.DAYS, 30);
            userBaseInfoRepository.save(userInfo);
        }
        return success();
    }


    /**
     * 2019年9月30日 14:29:15
     * 更新用户基础信息
     * @param redisUserInfo
     * @param dto
     * @return
     */
    public String updateUserInfo(RedisUserInfo redisUserInfo, UpdateUserInfoDTO dto)
    {
        //TODO
        
        
        
        return success();
    }


    /**
     * 2019年10月17日 09:29:22
     * 用户签到功能
     * @param redisUserInfo
     * @return
     */
    public String userSign(RedisUserInfo redisUserInfo)
    {
        //持续签到天数
        int keepSignDays = 0;
        //查询用户当天是否已经签到
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date now = new Date();
        MCUserSignInfoEntity info = userSignInfoRepository.findFirstBySignDate(format.format(now));
        if(null == info || 0 == info.getId())
        {
            return success();
        }
        //获取前一天签到情况
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        MCUserSignInfoEntity prefixInfo = userSignInfoRepository.findFirstBySignDate(format.format(calendar.getTime()));
        if(null != prefixInfo && 0 < prefixInfo.getId())
        {
            MCUserSignDetailEntity prefixDetail = userSignDetailRepository.findFirstByUserIdAndSignId(redisUserInfo.getId(), prefixInfo.getId());
            if(null != prefixDetail && 0 < prefixDetail.getId())
            {
                keepSignDays = prefixDetail.getDays();
            }
        }
        MCUserSignDetailEntity detail = userSignDetailRepository.findFirstByUserIdAndSignId(redisUserInfo.getId(), info.getId());
        if(null == detail || 0 == detail.getId())
        {
            detail = new MCUserSignDetailEntity();
            detail.setSignId(info.getId());
            detail.setUserId(redisUserInfo.getId());
            detail.setComment("");
            detail.setDays(keepSignDays + 1);
            detail.setCreateDate(now);
            userSignDetailRepository.save(detail);
        }
        return success();
    }
    
}